package com.kins.executer.handlers.common.business;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.kins.easycare.core.utils.SpringContextHolder;
import com.kins.executer.config.RagFlowConfig;
import com.kins.executer.constants.Constant;
import com.kins.executer.constants.DataConstant;
import com.kins.executer.enums.AiModelTypeEnum;
import com.kins.executer.factorys.AiModelFactory;
import com.kins.executer.handlers.common.base.AiModelExecuterHandler;
import com.kins.executer.handlers.common.base.ExecuterHandler;
import com.kins.executer.utils.ParamLogUtils;
import com.kins.executer.vo.MappingParamVo;
import com.kins.so.knowledgebase.constant.RagflowApi;
import com.kins.so.knowledgebase.entity.RagFlowDocument;
import com.kins.so.knowledgebase.entity.RagflowLibrary;
import com.kins.so.knowledgebase.mapper.RagflowLibraryMapper;
import com.kins.so.knowledgebase.service.IKnowledgeBaseService;
import com.kins.so.somanage.entity.SoManage;
import com.kins.so.somanage.mapper.SoManageMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @Description:
 * @Author: 申科
 * @Date:2025/11/11 16:36
 */
@Slf4j
public class RagFlowAskHandler  extends ExecuterHandler {
    @Override
    public Map<String, Object> exe(Map<String,Object> inputMap, MappingParamVo vo) throws Exception{
        Map<String,  Object> returnMap = new HashMap<>();
        try{
            HashMap<String, Object> ragFlowAskReqMap = new HashMap<>();
            Object objDataSet = inputMap.get("dataSet_ids");
            Object kbObj = inputMap.get("kb_ids");
            List<String> dataSetList = Lists.newArrayList();
            List<String> kbList = Lists.newArrayList();
            if(objDataSet != null){
                List<String> dataSetIds = (List<String>) objDataSet;
                if(dataSetIds != null && dataSetIds.size()>0){
                    dataSetList.addAll(dataSetIds);
                }
            }
            if(kbObj != null){
                List<String> kbIds = (List<String>) kbObj;
                if(kbIds != null && kbIds.size()>0){
                    kbList.addAll(kbIds);
                }
            }
            Map<String, Object> flowDataMap = vo.getDataMap();
            if(flowDataMap != null && flowDataMap.size()>0){
                Object knowledgeObj = flowDataMap.get("knowledgeIds");
                if(knowledgeObj != null){
                    List<String> knowledgeIds = (List<String>) knowledgeObj;
                    if(knowledgeIds != null && knowledgeIds.size()>0){
                        dataSetList.addAll(knowledgeIds);
                    }
                }
                Object documentObj = flowDataMap.get("documentIds");
                if(documentObj != null){
                    List<String> documentIds = (List<String>) documentObj;
                    if(documentIds != null && documentIds.size()>0){
                        dataSetList.addAll(documentIds);
                    }
                }
            }

            getPublicKnowledgeAndDocument(vo.getServiceArrangeId(),dataSetList,kbList, MapUtils.getString(inputMap, DataConstant.INPUTDATA_ORGCODE));

            String rg_customerName = null;
            String rg_customerCertNo = null;
            if(flowDataMap != null && flowDataMap.size()>0){
                rg_customerName = flowDataMap.get("rg_customerName") == null ? null:flowDataMap.get("rg_customerName").toString();
                rg_customerCertNo = flowDataMap.get("rg_customerCertNo") == null ? null:flowDataMap.get("rg_customerCertNo").toString();

            }
            getKnowledgeByStrategy(vo.getServiceArrangeId(),rg_customerName,rg_customerCertNo,dataSetList,kbList);//根据策略获取知识库和文档
            dataSetList = dataSetList.stream().distinct().collect(Collectors.toList());
            String question = MapUtils.getString(inputMap,"question");
            String ext_data = initBaseData(inputMap,vo,dataSetList);

            ragFlowAskReqMap.put("dataset_ids",dataSetList);
            ragFlowAskReqMap.put("kb_ids",kbList.stream().distinct().collect(Collectors.toList()));
            ragFlowAskReqMap.put("question",question);
            ragFlowAskReqMap.put("ext_data",ext_data);

            log.info("开始请求ragflow ask接口，请求参数："+ JSON.toJSONString(ragFlowAskReqMap));
            HashMap<String,Object> ragAswerMap = ask(ragFlowAskReqMap);
            log.info("接收到的ragflow ask接口响应内容："+JSON.toJSONString(ragAswerMap));
//            String returnStr = RestTemplateUtils.post(modelUrl,JSON.toJSONString(inputMap));
//            returnMap = JSON.parseObject(returnStr,HashMap.class);
//            JSONObject obj = (JSONObject) (returnMap.get("data"));
            HashMap<String,Object> returnData = (HashMap<String, Object>) ragAswerMap.get("data");
//            returnMap.put("answer",obj.getString("answer"));
            List<Object> chunks = null;
            HashMap<String,Object> reference = (HashMap<String, Object>) returnData.get("reference");
            if(reference != null){
                chunks = (List<Object>) reference.get("chunks");
            }
            //截取移除思考过程
            String answerResult = MapUtils.getString(returnData,"answer");
            if(StringUtils.isNotEmpty(answerResult)&& answerResult.indexOf("</think>")>-1){
                String[] arr = answerResult.split("</think>");
                if(arr.length==2){
                    answerResult = arr[1];
                }
            }
            HashMap<String,Object> ragResultMap = new HashMap<>();
            ragResultMap.put("answer",answerResult);
            ragResultMap.put("chunks",chunks);
            returnMap.put("answer",JSON.toJSONString(ragResultMap));
            returnMap.put(Constant.ACTION_KEY,Constant.SUCCESS_STATUS);
        }catch (Exception e){
            logger.error(e.getMessage(), e);
            //说明执行数据服务异常
            String info = ParamLogUtils.createLogInfo(vo,e);
            logger.error(info);
            returnMap.put(Constant.ACTION_KEY,Constant.NO_SUCCESS_STATUS);
            returnMap.put(Constant.ACTIONINFO_KEY,"调用服务失败："+info);
        }
        return returnMap;
    }

    private Map<String,Object> analysisTypeMap = new HashMap<>(){{
        put("jzdc","尽职调查报告");
        put("dhjc","贷后检查报告");
    }};

    private static final int RAGFlowOK = 0;

    private String initBaseData(Map<String, Object> inputMap, MappingParamVo vo, List<String> datasetIds){
        String question = MapUtils.getString(inputMap,"question");
        String businessNo = MapUtils.getString(inputMap,DataConstant.INPUTDATA_BUSINESSNO);
        //通过流水号+分析类型，查询相关的文档
        String analysisFileType = vo.getAnalysisType();
        if(StringUtils.isEmpty(analysisFileType) || StringUtils.isEmpty(businessNo)){
            return null;
        }
        IKnowledgeBaseService knowledgeBaseService = SpringBeanFactory.getBean(IKnowledgeBaseService.class);//获取bean
        List<RagFlowDocument> relatedFile = knowledgeBaseService.findTypeListBybusinessNo(businessNo);
        RagFlowConfig ragFlowConfig = SpringContextHolder.getBean(RagFlowConfig.class);
        //根据查到的文档ID,调用retrieval方法，查询相关数据
        List<String> document_ids = relatedFile.stream().filter(item->analysisFileType.equals(item.getFileType())).map(item->item.getDocId()).collect(Collectors.toList());
        if(document_ids.size()==0){
            return null;
        }
        Map<String, Object> reqMap = new HashMap<>();
        reqMap.put("dataset_ids",datasetIds);
        reqMap.put("document_ids",document_ids);
        reqMap.put("page","1");
        reqMap.put("page_size","5");
        reqMap.put("question:",question);
        String retrievalUrl = ragFlowConfig.getBaseUrl() + RAGFlowApi.retrieval;
        Map<String,Object> retrievalResp = knowledgeBaseService.requestRagFlowApi(reqMap,retrievalUrl, HttpMethod.POST);
        //取数据，优化提示词
        List<String> relatedData = processRetrievalResp(retrievalResp);
        return JSON.toJSONString(relatedData);

    }
    private List<String> processRetrievalResp(Map<String,Object> retrievalResp){
        int code = MapUtils.getIntValue(retrievalResp,"code");
        if(code != RAGFlowOK){
            log.error("调用retrieval异常：" +MapUtils.getString(retrievalResp,"message"));
            return null;
        }
        Map<String,Object> retrievalData = (Map<String, Object>) MapUtils.getMap(retrievalResp,"data");
        List<Map> chunks = (List<Map>) MapUtils.getObject(retrievalData,"chunks");
        List<String> relatedData = chunks.stream().map(item->MapUtils.getString(item,"content")).collect(Collectors.toList());
        return relatedData;
    }

    private Map<String,Object> buildParam(Map<String,Object> inputMap, MappingParamVo vo throws Exception{
        String modelKey = AiModelTypeEnum.RAG_FLOW_ASK.getModelKey();
        AiModelExecuterHandler aiModelExecuterHandler = AiModelFactory.getAiModelHandler(modelKey);
        if(aiModelExecuterHandler !=null){
            String[] str = StringUtils.split(modelKey, Constant.SPLIT_STR);
            inputMap.put("model_rpovider",str[0]);
            inputMap.put("model_name",str[1]);
            inputMap = aiModelExecuterHandler.buildParam(inputMap,vo);
        }
        return inputMap;
    }

    public HashMap ask(HashMap<String,Object> ragFlowAskReqMap){
        List<HashMap> result = getStreamData(ragFlowAskReqMap);
        if(result.size()<2){
            HashMap<String,Object> data = new HashMap<>();
            HashMap<String,Object> answer = new HashMap<>();
            answer.put("answer",result.get(0).get("message"));
            data.put("answer",answer);
            return data;
        }
        return result.get(result.size()-2);
    }

    public List<HashMap> getStreamData(HashMap<String,Object> ragFlowAskReqMap){
        RagFlowConfig ragFlowConfig  = SpringContextHolder.getBean(RagFlowConfig.class);
        String apiKey = ragFlowConfig.getApiKey();
        WebClient webClient = WebClient.builder().baseUrl(ragFlowConfig.getBaseUrl()).build();
        return webClient.post().uri(RAGFlowApi.getask())
                .contentType(MediaType.APPLICATION_JSON)
                .accept(MediaType.TEXT_EVENT_STREAM)
                .header("Authorization", "Bearer " + apiKey)
                .body(BodyInserters.fromObject(ragFlowAskReqMap))
                .retrieve()
                .bodyToFlux(HashMap.class).collectList().block();
    }
    /**
     * 获取服务编排流程的公共知识库
     *
     */
    public void getPublicKnowledgeAndDocument(String soManageId,List<String> dataSetList, List<String> kbList, String orgCode){
        SoManageMapper soManageMapper = SpringContextHolder.getBean(SoManageMapper.class);
        SoManage soManage = soManageMapper.get(soManageId);
        if(soManage != null && !StringUtils.isEmpty(soManage.getPublicKnowledgeType())){
            //根据公共知识库类型获取公共知识库和文档
            IKnowledgeBaseService knowledgeBaseService = SpringBeanFactory.getBean(IKnowledgeBaseService.class);
            RagFlowLibrary param = new RagflowLibrary();
            param.setOrgCode(orgCode);
            if("00".equals(soManage.getPublicKnowledgeType())){
                param.setTypeCode(soManage.getPublicKnowledgeType());
            }
            List<RagflowLibrary> ragflowLibraryList = knowledgeBaseService.findListByPermissionsByParam(param);
            List<String> ragflowLibIdList = ragflowLibraryList.stream().map(itme->item.getLibraryId()).collect(Collectors.toList());
            if(!ragflowLibIdList.isEmpty()){
                dataSetList.addAll(ragflowLibIdList);
            }
        }
    }
    /**
     * 根据策略获取知识库和文档
     */
    public void getKnowledgeByStrategy(String soManageId,
                                       String rg_customerName,
                                       String rg_customerCertNo,
                                       List<String> dataSetList,
                                       List<String> kbList){
        SoManageMapper soManageMapper = SpringContextHolder.getBean(SoManageMapper.class);
        SoManage soManage = soManageMapper.get(soManageId);
        if(soManage != null && "1".equals(soManage.getPrivateKnowledgeType()) && !StringUitls.isEmpty(rg_customerName) && !StringUitls.isEmpty(rg_customerCertNo)){
            RagflowLibraryMapper ragflowLibraryMapper = SpringContextHolder.getBean(RagflowLibraryMapper.class);
            RagflowLibrary library = new RagflowLibrary();
            library.setCustName(rg_customerName);
            library.setCertNo(rg_customerCertNo);
            RagflowLibrary ragflowLibrary = ragflowLibraryMapper.getInfoByCustInfo(library);
            if(ragflowLibrary != null){
                dataSetList.add(ragflowLibrary.getLibraryId());
            }
        }
    }
}
